require('dotenv').config();
const express = require('express');
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const cors = require('cors');
const os = require('os');
// const helmet = require('helmet');
const morgan = require('morgan');
const sharp = require('sharp');
const { v4: uuidv4 } = require('uuid');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcryptjs');

const app = express();
const PORT = process.env.PORT || 3000;

// 路径配置 - 兼容Windows和Linux
const getUploadsPath = () => {
  // 从环境变量获取配置路径，如果没有则使用默认路径
  let configPath = process.env.UPLOAD_PATH;
  
  if (os.platform() === 'linux') {
    configPath = process.env.LIN_UPLOAD_PATH;
  }

  if (configPath) {
    // 如果是绝对路径，直接使用
    if (path.isAbsolute(configPath)) {
      return configPath;
    }
    // 如果是相对路径，相对于项目根目录
    return path.join(__dirname, configPath);
  }
  
  // 默认路径：项目根目录下的uploads文件夹
  return path.join(__dirname, 'uploads');
};

// 初始化上传目录
const UPLOADS_BASE_PATH = getUploadsPath();
const THUMBNAILS_PATH = path.join(UPLOADS_BASE_PATH, 'thumbnails');

// 确保上传目录存在
const ensureUploadDirs = () => {
  try {
    if (!fs.existsSync(UPLOADS_BASE_PATH)) {
      fs.mkdirSync(UPLOADS_BASE_PATH, { recursive: true });
      console.log(`✅ 创建上传目录: ${UPLOADS_BASE_PATH}`);
    }
    
    if (!fs.existsSync(THUMBNAILS_PATH)) {
      fs.mkdirSync(THUMBNAILS_PATH, { recursive: true });
      console.log(`✅ 创建缩略图目录: ${THUMBNAILS_PATH}`);
    }
    
    // 检查目录权限
    try {
      fs.accessSync(UPLOADS_BASE_PATH, fs.constants.W_OK);
      console.log(`✅ 上传目录可写: ${UPLOADS_BASE_PATH}`);
    } catch (err) {
      console.error(`❌ 上传目录不可写: ${UPLOADS_BASE_PATH}`);
      process.exit(1);
    }
    
  } catch (error) {
    console.error(`❌ 创建目录失败: ${error.message}`);
    process.exit(1);
  }
};

// 应用启动时创建目录
ensureUploadDirs();

// JWT 配置
const JWT_CONFIG = {
  secret: process.env.JWT_SECRET || 'fallback-secret-key',
  expiresIn: process.env.JWT_EXPIRES_IN || '7d'
};

// 管理员凭据（生产环境应该使用数据库）
const ADMIN_CREDENTIALS = {
  username: process.env.ADMIN_USERNAME || 'admin',
  password: process.env.ADMIN_PASSWORD || 'admin123'
};

// 中间件
// app.use(helmet());
app.use(cors());
app.use(morgan('combined'));
app.use(express.json());
app.use('/uploads', express.static(UPLOADS_BASE_PATH));
app.use(express.static('public'));

// Multer 配置
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, UPLOADS_BASE_PATH);
  },
  filename: (req, file, cb) => {
    const uniqueName = `${uuidv4()}-${Date.now()}${path.extname(file.originalname)}`;
    cb(null, uniqueName);
  }
});

// 文件过滤器
const fileFilter = (req, file, cb) => {
  const allowedTypes = /jpeg|jpg|png|gif|webp|bmp/;
  const extname = allowedTypes.test(path.extname(file.originalname).toLowerCase());
  const mimetype = allowedTypes.test(file.mimetype);

  if (mimetype && extname) {
    return cb(null, true);
  } else {
    cb(new Error('只允许上传图片文件 (JPEG, PNG, GIF, WEBP, BMP)'));
  }
};

// Multer 实例
const upload = multer({
  storage: storage,
  limits: {
    fileSize: parseInt(process.env.MAX_FILE_SIZE) || 10 * 1024 * 1024, // 从环境变量读取或使用默认10MB
    files: 5 // 最多5个文件
  },
  fileFilter: fileFilter
});

// JWT 认证中间件
const authenticateToken = (req, res, next) => {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

  if (!token) {
    return res.status(401).json({ error: '访问令牌必填' });
  }

  jwt.verify(token, JWT_CONFIG.secret, (err, user) => {
    if (err) {
      return res.status(403).json({ error: '令牌无效或已过期' });
    }
    req.user = user;
    next();
  });
};

// 错误处理中间件
app.use((error, req, res, next) => {
  if (error instanceof multer.MulterError) {
    if (error.code === 'LIMIT_FILE_SIZE') {
      return res.status(400).json({ error: '文件大小超过限制' });
    }
    if (error.code === 'LIMIT_FILE_COUNT') {
      return res.status(400).json({ error: '文件数量超过限制' });
    }
  }
  res.status(400).json({ error: error.message });
});

// 生成缩略图函数
const generateThumbnail = async (sourcePath, filename, width = 200, height = 200) => {
  const thumbnailName = `thumb-${filename}`;
  const thumbnailPath = path.join(THUMBNAILS_PATH, thumbnailName);

  await sharp(sourcePath)
    .resize(width, height, {
      fit: 'inside',
      withoutEnlargement: true
    })
    .jpeg({ quality: 80 })
    .toFile(thumbnailPath);

  return thumbnailName;
};

// 图片信息获取函数
const getImageInfo = async (filePath) => {
  const image = sharp(filePath);
  const metadata = await image.metadata();
  
  return {
    width: metadata.width,
    height: metadata.height,
    format: metadata.format,
    size: metadata.size,
    space: metadata.space,
    channels: metadata.channels
  };
};

// 路径配置信息接口
app.get('/config/paths', authenticateToken, (req, res) => {
  res.json({
    uploadsPath: UPLOADS_BASE_PATH,
    thumbnailsPath: THUMBNAILS_PATH,
    platform: process.platform,
    separator: path.sep
  });
});

// 磁盘空间信息接口
app.get('/config/disk-usage', authenticateToken, async (req, res) => {
  try {
    const getDiskUsage = (dirPath) => {
      let totalSize = 0;
      let fileCount = 0;
      
      const calculateSize = (dir) => {
        const items = fs.readdirSync(dir);
        items.forEach(item => {
          const itemPath = path.join(dir, item);
          const stat = fs.statSync(itemPath);
          
          if (stat.isDirectory()) {
            calculateSize(itemPath);
          } else {
            totalSize += stat.size;
            fileCount++;
          }
        });
      };
      
      if (fs.existsSync(dirPath)) {
        calculateSize(dirPath);
      }
      
      return { totalSize, fileCount };
    };
    
    const uploadsUsage = getDiskUsage(UPLOADS_BASE_PATH);
    const thumbnailsUsage = getDiskUsage(THUMBNAILS_PATH);
    
    res.json({
      success: true,
      uploads: {
        path: UPLOADS_BASE_PATH,
        totalSize: uploadsUsage.totalSize,
        totalSizeMB: (uploadsUsage.totalSize / 1024 / 1024).toFixed(2),
        fileCount: uploadsUsage.fileCount
      },
      thumbnails: {
        path: THUMBNAILS_PATH,
        totalSize: thumbnailsUsage.totalSize,
        totalSizeMB: (thumbnailsUsage.totalSize / 1024 / 1024).toFixed(2),
        fileCount: thumbnailsUsage.fileCount
      },
      total: {
        size: uploadsUsage.totalSize + thumbnailsUsage.totalSize,
        sizeMB: ((uploadsUsage.totalSize + thumbnailsUsage.totalSize) / 1024 / 1024).toFixed(2),
        fileCount: uploadsUsage.fileCount + thumbnailsUsage.fileCount
      }
    });
  } catch (error) {
    console.error('获取磁盘使用情况错误:', error);
    res.status(500).json({ error: '获取磁盘使用情况失败' });
  }
});

// 公开路由 - 登录
app.post('/auth/login', async (req, res) => {
  try {
    const { username, password } = req.body;

    if (!username || !password) {
      return res.status(400).json({ error: '用户名和密码必填' });
    }

    // 简单的用户验证（生产环境应该使用数据库）
    if (username !== ADMIN_CREDENTIALS.username || password !== ADMIN_CREDENTIALS.password) {
      return res.status(401).json({ error: '用户名或密码错误' });
    }

    // 生成JWT令牌
    const token = jwt.sign(
      { 
        username: username,
        role: 'admin'
      },
      JWT_CONFIG.secret,
      { expiresIn: JWT_CONFIG.expiresIn }
    );

    res.json({
      success: true,
      message: '登录成功',
      token: token,
      user: {
        username: username,
        role: 'admin'
      },
      expiresIn: JWT_CONFIG.expiresIn
    });
  } catch (error) {
    console.error('登录错误:', error);
    res.status(500).json({ error: '登录失败' });
  }
});

// 令牌验证接口
app.post('/auth/verify', authenticateToken, (req, res) => {
  res.json({
    success: true,
    user: req.user,
    valid: true
  });
});

// 受保护的路由 - 单文件上传
app.post('/upload/single', authenticateToken, upload.single('image'), async (req, res) => {
  try {
    if (!req.file) {
      return res.status(400).json({ error: '请选择要上传的文件' });
    }

    const imageInfo = await getImageInfo(req.file.path);
    const thumbnailName = await generateThumbnail(req.file.path, req.file.filename);

    res.json({
      success: true,
      message: '文件上传成功',
      file: {
        id: uuidv4(),
        originalName: req.file.originalname,
        filename: req.file.filename,
        thumbnail: thumbnailName,
        path: `/uploads/${req.file.filename}`,
        thumbnailPath: `/uploads/thumbnails/${thumbnailName}`,
        size: req.file.size,
        mimetype: req.file.mimetype,
        imageInfo: imageInfo,
        uploadedAt: new Date().toISOString(),
        uploadedBy: req.user.username
      }
    });
  } catch (error) {
    console.error('上传错误:', error);
    res.status(500).json({ error: '文件处理失败' });
  }
});

// 受保护的路由 - 多文件上传
app.post('/upload/multiple', authenticateToken, upload.array('images', 5), async (req, res) => {
  try {
    if (!req.files || req.files.length === 0) {
      return res.status(400).json({ error: '请选择要上传的文件' });
    }

    const files = await Promise.all(
      req.files.map(async (file) => {
        const imageInfo = await getImageInfo(file.path);
        const thumbnailName = await generateThumbnail(file.path, file.filename);

        return {
          id: uuidv4(),
          originalName: file.originalname,
          filename: file.filename,
          thumbnail: thumbnailName,
          path: `/uploads/${file.filename}`,
          thumbnailPath: `/uploads/thumbnails/${thumbnailName}`,
          size: file.size,
          mimetype: file.mimetype,
          imageInfo: imageInfo,
          uploadedAt: new Date().toISOString(),
          uploadedBy: req.user.username
        };
      })
    );

    res.json({
      success: true,
      message: `${files.length} 个文件上传成功`,
      files: files
    });
  } catch (error) {
    console.error('多文件上传错误:', error);
    res.status(500).json({ error: '文件处理失败' });
  }
});

// 受保护的路由 - 获取文件列表
app.get('/files', authenticateToken, (req, res) => {
  fs.readdir(UPLOADS_BASE_PATH, (err, files) => {
    if (err) {
      return res.status(500).json({ error: '无法读取文件列表' });
    }

    const imageFiles = files.filter(file => {
      const ext = path.extname(file).toLowerCase();
      return ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp'].includes(ext) && 
             !file.startsWith('thumb-'); // 排除缩略图文件
    });

    const fileList = imageFiles.map(file => {
      const filePath = path.join(UPLOADS_BASE_PATH, file);
      const stats = fs.statSync(filePath);
      const thumbnailFile = `thumb-${file}`;
      const thumbnailPath = path.join(THUMBNAILS_PATH, thumbnailFile);
      const hasThumbnail = fs.existsSync(thumbnailPath);
      
      return {
        filename: file,
        path: `/uploads/${file}`,
        thumbnailPath: hasThumbnail ? `/uploads/thumbnails/${thumbnailFile}` : null,
        size: stats.size,
        uploadedAt: stats.birthtime,
        hasThumbnail: hasThumbnail
      };
    });

    res.json({
      success: true,
      files: fileList,
      total: fileList.length,
      uploadPath: UPLOADS_BASE_PATH
    });
  });
});

// 受保护的路由 - 删除文件
app.delete('/files/:filename', authenticateToken, (req, res) => {
  const filename = req.params.filename;
  const filePath = path.join(UPLOADS_BASE_PATH, filename);
  const thumbnailPath = path.join(THUMBNAILS_PATH, `thumb-${filename}`);

  // 检查文件是否存在
  if (!fs.existsSync(filePath)) {
    return res.status(404).json({ error: '文件不存在' });
  }

  try {
    // 删除原文件
    fs.unlinkSync(filePath);

    // 删除缩略图（如果存在）
    if (fs.existsSync(thumbnailPath)) {
      fs.unlinkSync(thumbnailPath);
    }

    res.json({
      success: true,
      message: '文件删除成功'
    });
  } catch (error) {
    console.error('删除文件错误:', error);
    res.status(500).json({ error: '文件删除失败' });
  }
});

// 公开路由 - 健康检查
app.get('/health', (req, res) => {
  const diskInfo = {
    uploadsPath: UPLOADS_BASE_PATH,
    uploadsExists: fs.existsSync(UPLOADS_BASE_PATH),
    thumbnailsExists: fs.existsSync(THUMBNAILS_PATH),
    platform: process.platform
  };

  try {
    if (fs.existsSync(UPLOADS_BASE_PATH)) {
      diskInfo.uploadsWritable = true;
      const testFile = path.join(UPLOADS_BASE_PATH, '.write-test');
      fs.writeFileSync(testFile, 'test');
      fs.unlinkSync(testFile);
    }
  } catch (error) {
    diskInfo.uploadsWritable = false;
  }

  res.json({
    status: 'ok',
    timestamp: new Date().toISOString(),
    uptime: process.uptime(),
    authenticated: false,
    disk: diskInfo
  });
});

// 受保护的健康检查
app.get('/health/secure', authenticateToken, (req, res) => {
  res.json({
    status: 'ok',
    timestamp: new Date().toISOString(),
    uptime: process.uptime(),
    authenticated: true,
    user: req.user,
    uploadPath: UPLOADS_BASE_PATH
  });
});

// 首页
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

// 404 处理
app.use((req, res) => {
  res.status(404).json({ error: '接口不存在' });
});

// 全局错误处理
app.use((error, req, res, next) => {
  console.log('全局错误:', error);
  res.status(500).json({ error: '服务器内部错误' });
});

app.listen(PORT, () => {
  console.log(`🔐 图片上传服务运行在 http://localhost:${PORT}`);
  console.log(`📁 上传目录: ${UPLOADS_BASE_PATH}`);
  console.log(`🖼️  缩略图目录: ${THUMBNAILS_PATH}`);
  console.log(`💾 平台: ${process.platform}`);
  console.log(`🔑 默认管理员: ${ADMIN_CREDENTIALS.username}`);
  console.log(`🗝️  JWT密钥: ${JWT_CONFIG.secret ? '已设置' : '未设置'}`);
  console.log(`📏 文件大小限制: ${(parseInt(process.env.MAX_FILE_SIZE) || 10 * 1024 * 1024) / 1024 / 1024}MB`);
});